Hook up `cargo update` to pkgids
authorAlex Crichton <alex@alexcrichton.com>
Mon, 22 Sep 2014 00:22:26 +0000 (17:22 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 22 Sep 2014 22:42:00 +0000 (15:42 -0700)
src/cargo/core/resolver.rs
src/cargo/ops/cargo_generate_lockfile.rs

index 3e5f6b90ce6df5fd7b7c195aeba4b3c4b674d079..6815fcc78f384e0b05bca41e7cd4175ef72ac205 100644 (file)
@@ -2,19 +2,12 @@ use std::collections::HashMap;
 use std::fmt;
 
 use serialize::{Encodable, Encoder, Decodable, Decoder};
-use util::profile;
-use util::graph::{Nodes, Edges};
-
-use core::{
-    Dependency,
-    PackageId,
-    Registry,
-    SourceId,
-};
-
 use semver;
 
-use util::{CargoResult, Graph, human, internal};
+use core::{Dependency, PackageId, Registry, SourceId, PackageIdSpec};
+use util::graph::{Nodes, Edges};
+use util::profile;
+use util::{CargoResult, Graph, human, internal, ChainError};
 
 #[deriving(PartialEq, Eq)]
 pub struct Resolve {
@@ -208,6 +201,30 @@ impl Resolve {
     pub fn deps(&self, pkg: &PackageId) -> Option<Edges<PackageId>> {
         self.graph.edges(pkg)
     }
+
+    pub fn query(&self, spec: &str) -> CargoResult<&PackageId> {
+        let spec = try!(PackageIdSpec::parse(spec).chain_error(|| {
+            human(format!("invalid package id specification: `{}`", spec))
+        }));
+        let mut ids = self.iter().filter(|p| spec.matches(*p));
+        let ret = match ids.next() {
+            Some(id) => id,
+            None => return Err(human(format!("package id specification `{}` \
+                                              matched no packages", spec))),
+        };
+        match ids.next() {
+            Some(other) => {
+                let mut msg = format!("Ambiguous package id specification: \
+                                       `{}`\nMatching packages:\n  {}\n  {}",
+                                      spec, ret, other);
+                for id in ids {
+                    msg = format!("{}\n  {}", msg, id);
+                }
+                Err(human(msg))
+            }
+            None => Ok(ret)
+        }
+    }
 }
 
 impl fmt::Show for Resolve {
index 7e6327d56a1748c71ef8f91921029c2a2203aa3f..0c214a99b185fb69c8a9e8b44531cf680e0435d3 100644 (file)
@@ -54,12 +54,12 @@ pub fn update_lockfile(manifest_path: &Path,
     let sources = match to_update {
         Some(name) => {
             let mut to_avoid = HashSet::new();
-            for dep in resolve.iter().filter(|d| d.get_name() == name.as_slice()) {
-                if aggressive {
-                    fill_with_deps(&resolve, dep, &mut to_avoid);
-                } else {
-                    to_avoid.insert(dep);
-                }
+            let dep = try!(resolve.query(name.as_slice()));
+            fill_with_deps(&resolve, dep, &mut to_avoid);
+            if aggressive {
+                fill_with_deps(&resolve, dep, &mut to_avoid);
+            } else {
+                to_avoid.insert(dep);
             }
             resolve.iter().filter(|pkgid| !to_avoid.contains(pkgid))
                    .map(|pkgid| pkgid.get_source_id().clone()).collect()